/*-------------------------------------------
UART串口通信
add by mtd at 20240521
----------------------------------------------*/
#include "taiic_uart.h"
#include "taiic_uart_sum.h"
#include <fstream>
#include "rk_debug.h"
#include <stdio.h>
#include <unistd.h> // Unix 标准函数定义
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <fcntl.h> // 文件控制定义
#include <iostream>
#include <termios.h> // PPSIX 终端控制定义
#include <cstring>   // 字符串功能
#include <errno.h>   // 错误号定义
#include <pthread.h> // 线程

//
using namespace std;
mutex mtx_ringbuffer;
RingBuf_Taiic_U serialData;

pthread_mutex_t mutex_Q = PTHREAD_MUTEX_INITIALIZER; // 初始化互斥锁
unsigned int queue_node_count = 0;

int validLen = 0;
int readLen = 0;
ofstream file_a;
/*-----------------------------function define--------------------------*/
void appendToPcmFile(const char *filename, uint8_t *data, unsigned int length)
{
    // 以二进制和追加模式打开文件
    std::ofstream file(filename, std::ios::binary | std::ios::app);
    if (!file)
    {
        // 处理文件打开失败的情况
        std::cerr << "Failed to open file for appending: " << filename << std::endl;
        return;
    }

    // 将数据写入文件
    file.write(reinterpret_cast<const char *>(data), length);

    // 检查是否所有数据都已写入
    if (!file)
    {
        std::cerr << "Failed to write data to file: " << filename << std::endl;
    }

    // 关闭文件（虽然不是必须的，因为析构函数会自动调用）
    file.close();
}

int audio_frame_analysis_function(uint8_t *data, unsigned int length)
{

    int ret = 0;

    if ((data == NULL) || (length < 4)) // 音频帧头有音频类型、帧号占有3个字节，数据长度 如果小于4，代表帧不合格直接返回
    {
        return -1;
    }
    else
    {
        // 获取音频帧帧头内容
        // audioAnalysis.pdata = reinterpret_cast<uint8_t *>(data);
        audioAnalysis.pdata = data;
        audioAnalysis.audio_type = audioAnalysis.pdata[0];
        // audioAnalysis.frame_num  = 0;
        memcpy(&audioAnalysis.frame_num, &audioAnalysis.pdata[1], 2); // memcpy(&audioAnalysis.frame_num, &audioAnalysis.pdata[1], sizeof(audioAnalysis.frame_num));
        audioAnalysis.frame_num = big_to_little_u16(&audioAnalysis.frame_num);
        //20240603 add///////////////////
        audioAnalysis.dif = audioAnalysis.frame_num - audioAnalysis.last_frame_num;
        printf("dif=%d,frame_cnt=%d,last_frame_cnt=%d\n",audioAnalysis.frame_num-audioAnalysis.last_frame_num, audioAnalysis.frame_num, audioAnalysis.last_frame_num);
        audioAnalysis.last_frame_num = audioAnalysis.frame_num;
        ////////////////////////////////
        audioAnalysis.audio_data = audioAnalysis.pdata + 3;
        audioAnalysis.audio_data_length = length - 3;

        // printf("num %d,len %d,type=%d\n", audioAnalysis.frame_num, audioAnalysis.audio_data_length, audioAnalysis.audio_type);

        //if(audioAnalysis.audio_type == 1) // 气导原始数据
        if((audioAnalysis.audio_type == 1)&&(audioAnalysis.dif==1)) //气导原始数据
        { 
            appendToPcmFile(audioAnalysis.air_filename, audioAnalysis.audio_data, audioAnalysis.audio_data_length);

            // fwrite(audioAnalysis.audio_data, sizeof(unsigned char), audioAnalysis.audio_data_length, audioAnalysis.file_air);  //size_t len = fwrite(audioAnalysis.audio_data, sizeof(unsigned char), audioAnalysis.audio_data_length, audioAnalysis.file_air);
        }
        else if (audioAnalysis.audio_type == 2) // 骨导原始数据
        {
            // 创建并打开文件
            audioAnalysis.file_bone = fopen(audioAnalysis.bone_filename, "a+");

            size_t len = fwrite(audioAnalysis.audio_data, 2, length / 2, audioAnalysis.file_bone);
        }
        else if (audioAnalysis.audio_type == 3) // 气导+骨导数据
        {
            // 创建并打开文件
            audioAnalysis.file_air = fopen(audioAnalysis.air_filename, "a+");
            audioAnalysis.file_bone = fopen(audioAnalysis.bone_filename, "a+");
        }
        else // 帧类型错误，返回
        {
            ret = -1;
        }
    }

    return ret;
}

int frame_analysis_function(uint8_t *data, unsigned int length)
{
    int ret;
    uint8_t frame_flag = 0;
    uint8_t from = 0;
    uint8_t to = 0;
    uint8_t command_id = 0;
    unsigned short data_length = 0;
    unsigned short check_sum_cal = 0;
    unsigned short check_sum_read = 0;
    uint8_t temp_buffer[FRAME_BUFFER_LENGTH_MAX] = {0};
    unsigned short temp_data_length = 0;

    if ((data == NULL) || (length > FRAME_BUFFER_LENGTH_MAX))
    {
        return -1;
    }
    else
    {
        memcpy(temp_buffer, save_buffer, save_data_length);   // 拷贝上一次未解析完数据
        temp_data_length = save_data_length + length;         // 计算要解析的数据总长度
        memcpy(&temp_buffer[save_data_length], data, length); // 拷贝这一次读取到的所有数据
    }

    for (int i = 0; i < temp_data_length; i++)
    {
        if (temp_buffer[i] == FRAME_FLAG) // 查找帧头标志位
        {
            if ((temp_data_length - i) >= FRAME_HEADER_LENGTH) // 判断剩余长度是否够解析帧头内容
            {
                from = temp_buffer[i + FRAME_FROM_INDEX];
                to = temp_buffer[i + FRAME_TO_INDEX];
                command_id = temp_buffer[i + FRAME_COMMAND_ID_INDEX];

                memcpy(&data_length, &temp_buffer[i + FRAME_DATA_LENGTH_INDEX], 2);
                data_length = big_to_little_u16(&data_length);
                
                
                if ((data_length >= 2)&&(data_length < FRAME_BUFFER_LENGTH_MAX) && (from == 0x02) && (to == 0x04)) // 判断读取到的数据长度是否有效，以及来源与目的是否是副板到主板
                {
                    frame_total_length=FRAME_TOTAL_LENGTH(data_length);
                    if ((i+frame_total_length) <= temp_data_length) // 判断读取数据是否够一整帧
                    {
                        memcpy(data_buffer, &temp_buffer[i], frame_total_length);                    // 保存一整帧数据
                        save_data_length = temp_data_length - frame_total_length;                    // 剩余数据下回解析
                        memcpy(save_buffer, &temp_buffer[i+frame_total_length], save_data_length); // 剩余数据下回解析
                        
                        //计算校验值
                        check_sum_cal = calc_crc16(data_buffer, FRAME_CHECK_DATA_LENGTH(data_length), CHECKSUM_INIT_VALUE);
                        check_sum_read = big_to_little_u16(&data_buffer[FRAME_CHECKSUM_INDEX(data_length)]);//check_sum_read = big_to_little_u16(&data_buffer[FRAME_CHECKSUM_INDEX(data_length)]);
                        if (check_sum_cal == check_sum_read) // 判断校验结果与校验位数据是否一致
                        {
                            if (recv_data_display_flag)
                            {
                                printf("data: from %02x to %02x command_id %02x length %d checksum %04x !\n", from, to, command_id, data_length, check_sum_read);
                            }
                            
                            if (command_id == 0x21)
                            {
                                audio_frame_analysis_function(&data_buffer[FRAME_HEADER_LENGTH], data_length);
                            }
                        }
                        else
                        {
                            // 校验失败
                            if (real_time_recv_serial_data_flag)
                            {
                                printf("校验失败：%04x , %04x\n", check_sum_cal, check_sum_read);
                            }
                        }

                    }
                    else{
                        // 数据不完整，继续等待
                        save_data_length = temp_data_length;
                        memcpy(save_buffer, temp_buffer, temp_data_length);
                        if (real_time_recv_serial_data_flag)
                        {
                            printf("不够解析整帧,数据不完整,继续等待,i = %d, length = %d\n", i, temp_data_length);
                        }
                        break;
                    }
                }
                else
                {
                    // 数据错误
                    if (real_time_recv_serial_data_flag)
                    {
                        printf("数据长度：%d，from：%02x，to：%02x\n", data_length);
                    }
                }
            }
            else
            {
                // 数据不完整，继续等待
                save_data_length = temp_data_length;
                memcpy(save_buffer, temp_buffer, temp_data_length);
                if (real_time_recv_serial_data_flag)
                {
                    printf("不够解析帧头，数据不完整，继续等待\n");
                }
                break;
            }
        }
       break;//退出for循环
    }
    return ret;
}

int frame_package_function(protocal_list_t instruct, void *data, unsigned short length)
{
    int ret;
    unsigned char send_buffer[FRAME_BUFFER_LENGTH_MAX] = {0};
    unsigned short data_length = 0;
    unsigned short check_sum = 0;

    // 判断传入参数
    if ((data == NULL) && (length != 0))
    {
        return -1;
    }
    // 填充帧内容
    send_buffer[FRAME_FLAG_INDEX] = 0xFE;                          // 帧头标准
    send_buffer[FRAME_FROM_INDEX] = 0x04;                          // 从主板
    send_buffer[FRAME_TO_INDEX] = 0x02;                            // 发往副板
    send_buffer[FRAME_COMMAND_ID_INDEX] = (unsigned char)instruct; // 指令
    data_length = big_to_little_u16(&length);
    memcpy(&send_buffer[FRAME_DATA_LENGTH_INDEX], &data_length, sizeof(data_length)); // 有效数据长度
    memcpy(&send_buffer[FRAME_DATA_START_ADDR_INDEX], data, length);                  // 有效数据
    // 计算校验值
    check_sum = calc_crc16(send_buffer, FRAME_CHECK_DATA_LENGTH(length), CHECKSUM_INIT_VALUE);
    printf("check_sum = %x\n", check_sum);
    check_sum = big_to_little_u16(&check_sum);
    printf("check_sum = %x\n", check_sum);
    memcpy(&send_buffer[FRAME_CHECKSUM_INDEX(length)], &check_sum, sizeof(check_sum)); // 校验值

    ret = serial_send_function(send_buffer, FRAME_TOTAL_LENGTH(length));

    return ret;
}
/*-------------------------serial-------------------------*/
// 打开串口设备
int open_serial_port(void)
{
    char error_info[256] = {0};

    serial_fd = open(SERIAL_PORT, O_RDWR);
    if (serial_fd == -1)
    {
        sprintf(error_info, "open_port: Unable to open %s\n", SERIAL_PORT);
        perror(error_info);
        return -1;
    }
    return 0;
}

// 设置串口参数
int set_serial_attribs(void)
{
    struct termios tty;
    memset(&tty, 0, sizeof(tty));
    if (tcgetattr(serial_fd, &tty) != 0)
    {
        perror("tcgetattr");
        return -1;
    }
    // 设置波特率
    cfsetispeed(&tty, BAUD_RATE);
    cfsetospeed(&tty, BAUD_RATE);
    printf("baud_rate = %d\n", BAUD_RATE);
#if 0
    // 设置CSIZE为CS8，即8位数据长度
    tty.c_cflag &= ~CSIZE;
    tty.c_cflag |= CS8;
    // 设置PARENB为0，即无校验位
    tty.c_cflag &= ~PARENB;
    // 设置CSTOPB为0，即1位停止位
    tty.c_cflag &= ~CSTOPB;
    // 设置CRTSCTS为0，即不使用硬件流控制
    tty.c_cflag &= ~CRTSCTS;
#else
    tty.c_cflag |= termios_c_cflag;
#endif
    // 设置CLOCAL和CREAD，使能接收器和本地模式
    tty.c_cflag |= (CLOCAL | CREAD);
    // 设置ICANON为0，即非规范模式，这样read就不会受行缓冲的影响
    tty.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
    // 设置OPOST为0，即禁用输出处理
    tty.c_oflag &= ~OPOST;
    tty.c_oflag &= ~(ONLCR | OCRNL);
    // 设置ICANON为0，即非规范模式
    tty.c_iflag &= ~(BRKINT | INPCK | ISTRIP);
    tty.c_iflag &= ~(ICRNL | INLCR);
    tty.c_iflag &= ~(IXON | IXOFF | IXANY);
    // 设置VMIN为1，VMAX为0，这样read就会一直阻塞，直到有数据可读
    tty.c_cc[VMIN] = 1;
    tty.c_cc[VTIME] = 0;
    if (tcsetattr(serial_fd, TCSANOW, &tty) != 0)
    {
        perror("tcsetattr");
        return -1;
    }

    return 0;
}
// 串口接收数据线程函数
void *serial_recv_pthread_function(void *arg)
{
    int ret = 0;
    uint8_t recv_buffer[512];

    while (true)
    {
        // 读取数据
        int len = read(serial_fd, recv_buffer, sizeof(recv_buffer));
        if (len < 0)
        {
            perror("read");
            close(serial_fd);
            pthread_exit((void *)&ret);
        }
        
        mtx_ringbuffer.lock();
        ret = serialData.writeRingbuffer(recv_buffer, len);
        mtx_ringbuffer.unlock();

        // printf("当前队列节点数：%d\n", getQueueNodeCount());
    }
}
// 数据帧解析线程函数
void *frame_analysis_pthread_function(void *arg)
{
    uint8_t read_buffer[65536];
    while (true)
    {
        mtx_ringbuffer.lock();
        validLen = serialData.getRingbufferValidLen();
        if (validLen > 0)
        {
            readLen = serialData.readRingbuffer(read_buffer, validLen);
            frame_analysis_function(read_buffer, readLen);
        }

        mtx_ringbuffer.unlock();
    }
}
// 串口发送数据函数
int serial_send_function(void *data, unsigned short data_len)
{
    int ret;

    if (data == NULL)
    {
        return -1;
    }

    ret = write(serial_fd, data, data_len);

    printf("send data: ");
    for (int i = 0; i < ret; i++)
    {
        printf("%02x ", ((unsigned char *)data)[i]);
    }
    printf("\n");

    return ret;
}
// 串口初始化
int serial_init(void)
{
    int ret;
    int arg = 100;
    //
    ret = open_serial_port();
    if (ret == -1)
    {
        return ret;
    }
    //
    ret = set_serial_attribs();
    if (ret == -1)
    {
        return ret;
    }
    // 初始化保存读取数据队列
    ret = initQueue(&read_data_queue);
    if (ret == -1)
    {
        printf("初始化队列失败！\n");
        return ret;
    }
    // 创建串口线程
    ret = pthread_create(&serial_read_pthread, NULL, serial_recv_pthread_function, (void *)&arg);
    if (ret == -1)
    {
        printf("创建串口接收线程失败！\n");
        return ret;
    }
    sleep(1);
    // 创建数据帧解析线程
    ret = pthread_create(&frame_analysis_pthread, NULL, frame_analysis_pthread_function, (void *)&arg);
    if (ret == -1)
    {
        printf("创建数据分析线程失败！\n");
        return ret;
    }
    return ret;
}
/*----------------------------------queue---------------------------------*/
// 初始化队列
int initQueue(Queue *q)
{
    int ret = -1;

    q->front = q->rear = (Node *)malloc(sizeof(Node));
    if (!q->front)
    {
        printf("内存分配失败\n");
        return ret;
    }
    q->front->next = NULL;
    ret = 0;

    return ret;
}

// 入队操作
int enQueue(Queue *q, unsigned char *data, unsigned int length)
{
    int ret = -1;

    // 判断入参
    if ((q == NULL) || (data == NULL) || (length == 0))
    {
        return ret;
    }
    // 创建新节点
    Node *newNode = (Node *)malloc(sizeof(Node));
    if (!newNode)
    {
        printf("内存分配失败\n");
        return ret;
    }
    // 根据数据长度创建数据存储空间
    pthread_mutex_lock(&mutex_Q); // 锁住互斥锁
    newNode->pdata = (unsigned char *)malloc(length);
    if (!newNode->pdata)
    {
        printf("内存分配失败\n");
        return ret;
    }
    // 拷贝数据到链表节点中
    memcpy(newNode->pdata, data, length);
    newNode->data_len = length;
    // 在链表尾部插入新节点
    newNode->next = NULL;
    q->rear->next = newNode;
    q->rear = newNode;
    // 更新队列节点计数
    queue_node_count++;
    pthread_mutex_unlock(&mutex_Q); // 解锁互斥锁
    ret = 0;

    return ret;
}

// 出队操作
unsigned int deQueue(Queue *q, unsigned char *data)
{
    int ret = 0;
    pthread_mutex_lock(&mutex_Q); // 锁住互斥锁
    if ((q == NULL) || (data == NULL))
    {
        return ret;
    }

    unsigned int data_len;

    if (q->front == q->rear)
    {
        printf("队列为空\n");
        return ret;
    }
    // 获取队头节点信息
    Node *tmp = q->front->next;
    memcpy(data, tmp->pdata, tmp->data_len);
    data_len = tmp->data_len;
    // 删除节点
    q->front->next = tmp->next;
    if (q->rear == tmp)
    {
        q->rear = q->front;
    }
    free(tmp->pdata);
    free(tmp);
    // 更新队列节点计数
    queue_node_count--;
    pthread_mutex_unlock(&mutex_Q); // 解锁互斥锁
    return data_len;
}

// 检查队列是否为空
bool isEmpty(Queue *q)
{
    pthread_mutex_lock(&mutex_Q);
    if (q == nullptr)
    {
        return true;
    }
    bool rst = (q->front == q->rear);
    pthread_mutex_unlock(&mutex_Q); // 解锁互斥锁

    return rst;
}

// 获取队列节点个数
unsigned int getQueueNodeCount(void)
{
    unsigned int count;

    // 读取节点个数值
    pthread_mutex_lock(&mutex_Q); // 锁住互斥锁
    count = queue_node_count;
    pthread_mutex_unlock(&mutex_Q); // 解锁互斥锁

    return count;
}
/*---------------------display---------------------------*/
int display_up_data_switch_cmd_function(void)
{
    int ret = 0;
    char read_data;
    unsigned char send_data = 0;

    printf(MESSAGE_UP_DATA_SWITCH_CMD);
    scanf("%s", &read_data);
    getchar();
    switch (read_data)
    {
    case '0':
        send_data = 0;
        ret = frame_package_function(up_data_switch_cmd, &send_data, sizeof(send_data));
        break;
    case '1':
        send_data = 1;
        ret = frame_package_function(up_data_switch_cmd, &send_data, sizeof(send_data));
        break;
    case 'e':
        /* code */
        return ret;

    default:
        printf("无效命令：%s！\n", read_data);
        ret = -1;
        break;
    }

    return ret;
}

int display_mode_switch_cmd_function(void)
{
    int ret = 0;
    char read_data;
    unsigned char send_data = 0;

    printf(MESSAGE_MODE_SWITCH_CMD);
    scanf("%s", &read_data);
    getchar();
    switch (read_data)
    {
    case '0':
        send_data = 0;
        ret = frame_package_function(mode_switch_cmd, &send_data, sizeof(send_data));
        break;
    case '1':
        send_data = 1;
        ret = frame_package_function(mode_switch_cmd, &send_data, sizeof(send_data));
        break;
    case '2':
        send_data = 2;
        ret = frame_package_function(mode_switch_cmd, &send_data, sizeof(send_data));
        break;
    case 'e':
        /* code */
        return ret;

    default:
        printf("无效命令：%s！\n", read_data);
        ret = -1;
        break;
    }

    return ret;
}

int display_audio_presentations_cmd_function(void)
{
    int ret = 0;
    char read_data[256];

    printf(MESSAGE_AUDIO_PRESENTATIONS_CMD);
    scanf("%s", &read_data);
    getchar();

    return ret;
}

int display_prompt_tone_play_cmd_function(void)
{
    int ret = 0;
    char read_data;
    unsigned char send_data = 0;

    printf(MESSAGE_PROMPT_TONE_PLAY_CMD);
    scanf("%s", &read_data);
    getchar();
    switch (read_data)
    {
    case '1':
        send_data = 1;
        break;
    case '2':
        send_data = 2;
        break;
    case '3':
        send_data = 3;
        break;
    case '4':
        send_data = 4;
        break;
    case '5':
        send_data = 5;
        break;
    case '6':
        send_data = 6;
        break;
    case '7':
        send_data = 7;
        break;
    case '8':
        send_data = 8;
        break;
    case '9':
        send_data = 9;
        break;
    case 'e':
        /* code */
        return ret;

    default:
        printf("无效命令：%s！\n", read_data);
        return -1;
    }

    ret = frame_package_function(prompt_tone_play_cmd, &send_data, sizeof(send_data));

    return ret;
}

int display_mic_data_type_cmd_function(unsigned char *data)
{
    int ret = 0;
    char read_data;

    if (data == NULL)
    {
        return -1;
    }

    printf(MESSAGE_MIC_DATA_TYPE_CMD);
    scanf("%s", &read_data);
    getchar();
    switch (read_data)
    {
    case '1':
        *data = 1; // 气导 原始信号
        break;
    case '2':
        *data = 2; // 骨导 原始信号
        break;
    case '3':
        *data = 3; // 气导+骨导 原始信号
        break;

    default:
        printf("无效命令：%s！\n", read_data);
        break;
    }

    return ret;
}

unsigned int display_mic_data_ctrl_cmd_function(void)
{
    unsigned int ret = 0;

    printf(MESSAGE_MIC_DATA_CTRL_CMD);
    scanf("%d", &ret);
    getchar();

    return ret;
}

int display_mic_data_request_cmd_function(void)
{
    int ret = 0;
    unsigned int time = 0;
    unsigned char send_data[2] = {0};

    time = display_mic_data_ctrl_cmd_function();

    ret = display_mic_data_type_cmd_function(&send_data[1]);
    if (ret != 0)
    {
        return ret;
    }

    // 开始传输音频数据
    send_data[0] = 1;
    ret = frame_package_function(mic_adta_request_cmd, &send_data, sizeof(send_data));
    // 延时
    sleep(time);
    // 停止传输音频数据
    send_data[0] = 0;
    ret = frame_package_function(mic_adta_request_cmd, &send_data, sizeof(send_data));

    return ret;
}

int display_battery_percentage_cmd_function(unsigned char *data)
{
    int ret = 0;
    unsigned char read_data;

    if (data == NULL)
    {
        return -1;
    }

    printf(MESSAGE_BATTERY_PERCENTAGE_CMD);
    scanf("%d", &read_data);
    getchar();
    *data = read_data;

    return ret;
}

int display_battery_voltage_cmd_function(unsigned char *data)
{
    int ret = 0;
    unsigned char read_data[2] = {0};

    if (data == NULL)
    {
        return -1;
    }

    printf(MESSAGE_BATTERY_VOLTAGE_CMD);
    scanf("%d", read_data);
    getchar();
    data[0] = read_data[1];
    data[1] = read_data[0];

    return ret;
}

int display_battery_status_cmd_function(unsigned char *data)
{
    int ret = 0;
    char read_data;

    printf(MESSAGE_BATTERY_STATUS_CMD);
    scanf("%s", &read_data);
    getchar();
    switch (read_data)
    {
    case '0':
        *data = 0;
        break;
    case '1':
        *data = 1;
        break;
    case '2':
        *data = 2;
        break;

    default:
        printf("无效命令：%s！\n", read_data);
        break;
    }

    return ret;
}

int display_battery_status_notify_cmd_function(void)
{
    int ret = 0;
    unsigned char send_data[4] = {0};

    ret = display_battery_status_cmd_function(&send_data[0]);
    if (ret != 0)
    {
        return ret;
    }

    ret = display_battery_voltage_cmd_function(&send_data[1]);
    if (ret != 0)
    {
        return ret;
    }

    ret = display_battery_percentage_cmd_function(&send_data[3]);
    if (ret != 0)
    {
        return ret;
    }

    ret = frame_package_function(battery_status_notify_cmd, &send_data, sizeof(send_data));

    return ret;
}

int display_inquire_firmware_info_cmd_function(void)
{
    int ret = 0;

    ret = frame_package_function(inquire_firmware_info_cmd, NULL, 0);

    return ret;
}

int display_parse_error_cmd_function(void)
{
    int ret = 0;
    unsigned char read_data;

    printf(MESSAGE_PARSE_ERROR_CMD);
    scanf("%x", &read_data);
    getchar();

    ret = frame_package_function(parse_error_cmd, &read_data, sizeof(read_data));

    return ret;
}

int display_send_select_function(void)
{
    int ret = 0;
    char read_data;

    while (true)
    {
        printf(MESSAGE_SEND_DATA);
        scanf("%s", &read_data);
        getchar();
        switch (read_data)
        {
        case '1':
            display_parse_error_cmd_function(); // 指令解析错误指令
            break;
        case '2':
            display_inquire_firmware_info_cmd_function(); // 固件版本信息查询指令
            break;
        case '3':
            display_battery_status_notify_cmd_function(); // 电池电量同步指令
            break;
        case '4':
            display_mic_data_request_cmd_function(); // MIC数据传输控制指令
            break;
        case '5':
            display_prompt_tone_play_cmd_function(); // 提示音播放指令
            break;
        case '6':
            display_audio_presentations_cmd_function(); // 主板端上行音频播放指令
            break;
        case '7':
            display_mode_switch_cmd_function(); // 通信模式切换指令
            break;
        case '8':
            display_up_data_switch_cmd_function(); // 通信上行是否传输指令
            break;
        case 'e':
            /* code */
            return ret; // 返回上一级

        default:
            printf("无效命令：%s！\n", read_data);
            break;
            ;
        }
        printf("执行完成！\n");
    }

    return ret;
}

int display_recv_select_function(void)
{
    int ret = 0;
    char read_data;

    printf(MESSAGE_RECV_SET);
    scanf("%s", &read_data);
    getchar();
    switch (read_data)
    {
    case '0':
        recv_data_display_flag = 0;
        printf("已关闭接收数据显示功能！\n");
        break;
    case '1':
        recv_data_display_flag = 1;
        printf("已开启接收数据显示功能！\n");
        break;
    case '2':
        real_time_recv_serial_data_flag = 1;
        printf("已开启实时读取串口功能！\n");
        getchar();
        real_time_recv_serial_data_flag = 0;
        printf("已关闭实时读取串口功能！\n");
        break;
    case 'e':
        /* code */
        return ret;

    default:
        printf("无效命令：%s！\n", read_data);
        break;
        ;
    }

    return ret;
}

int display_main_function(void)
{
    int ret = 0;
    char read_data;

    while (true)
    {
        printf(MESSAGE_MAIN);
        scanf("%s", &read_data);
        getchar();
        switch (read_data)
        {
        case '0':
            display_send_select_function();
            break;
        case '1':
            display_recv_select_function();
            break;
        case 'q':
            /* code */
            return ret;

        default:
            printf("无效命令：%s！\n", read_data);
            break;
        }
    }

    return ret;
}

/*-------------------------main-------------------------*/
int main(int argc, char **argv)
{
    RK_LOGD("Test v3 uart\n");
    serialData.bufferSize = RB_MAX_SIZE;
    serialData.initRingbuffer();

    // 串口初始化
    serial_init();
    // 窗口显示/数据帧收发处理
    display_main_function();
    // 退出程序
    printf("程序已退出!!!\n");
    serialData.releaseRingbuffer();

    return 0;
}
